export interface ImgReadResultProps {
  img: ImageBitmapSource;
  type: string;
  name: string;
}

export interface ImgCompressResultProps {
  blob: Blob | null;
  type: string;
  name: string;
}

const readImg = (file: File): Promise<ImgReadResultProps> => {
  return new Promise((resolve, reject) => {
    const img: ImageBitmapSource = new Image();
    const reader = new FileReader();
    reader.onload = function (e: any) {
      img.src = e.target.result;
    };
    reader.onerror = function (e) {
      reject(e);
    };
    reader.readAsDataURL(file);
    img.onload = function () {
      const { type, name } = file;
      resolve({ img, type, name });
    };
    img.onerror = function (e) {
      reject(e);
    };
  });
};

/**
 * 压缩图片 Compress image
 * @param img 被压缩的img对象 the compressed img objec
 * @param mx 触发压缩的图片最大宽度限制 Image maximum width limit that triggers compression
 * @param mh 触发压缩的图片最大高度限制 Maximum height limit for images that trigger compression
 */
const compressImg = async (
  file: File,
  mx: number = 1000,
  mh: number = 1000
): Promise<ImgCompressResultProps> => {
  const { type, name, img }: ImgReadResultProps = await readImg(file);
  return new Promise((resolve, reject) => {
    const canvas = document.createElement("canvas");
    const context = canvas.getContext("2d");
    const { width: originWidth, height: originHeight } = img as any;
    // 最大尺寸限制
    const maxWidth = 1000;
    const maxHeight = 1000;
    // 目标尺寸
    let targetWidth: number = originWidth;
    let targetHeight: number = originHeight;
    if (originWidth > maxWidth || originHeight > maxHeight) {
      if (originWidth / originHeight > 1) {
        //  宽图片
        targetWidth = maxWidth;
        targetHeight = Math.round(maxWidth * (originHeight / originWidth));
      } else {
        // 高图片
        targetHeight = maxHeight;
        targetWidth = Math.round(maxHeight * (originWidth / originHeight));
      }
    }
    canvas.width = targetWidth;
    canvas.height = targetHeight;
    context?.clearRect(0, 0, targetWidth, targetHeight);
    // 图片绘制
    context?.drawImage(
      img as CanvasImageSource,
      0,
      0,
      targetWidth,
      targetHeight
    );
    canvas.toBlob(function (blob: Blob | null) {
      resolve({ blob, type, name });
    }, type || "image/png");
  });
};

/**
 * 压缩图片 Compress image
 * @param img 被压缩的img对象 the compressed img object
 * @param fileName 文件名 filename
 * @param mx 触发压缩的图片最大宽度限制 Image maximum width limit that triggers compression
 * @param mh 触发压缩的图片最大高度限制 Maximum height limit for images that trigger compression
 * @return 文件对象 File object
 */
const toFile = async (
  file: File,
  fileName?: string,
  mx: number = 1000,
  mh: number = 1000
): Promise<File> => {
  const { blob, type, name }: ImgCompressResultProps = await compressImg(
    file,
    mx,
    mh
  );
  const fileData: File = new File([blob || new Blob()], fileName || name, {
    type,
  });
  return fileData;
};

export default toFile;
